//=====================1.symbol基本用法==============
"use strict";
let symbol = Symbol();
console.log(typeof symbol);

let s1 = Symbol();
let s2 = Symbol();
let s3 = Symbol('s3');
let s4 = Symbol('s4');
console.log(s1 == s2);
console.log(s3 == s4);
console.log(s2);
console.log(s3);

let sym = Symbol();
let symobj = Object(sym);
console.log(typeof symobj);

//======================2. 使用全局符号注册表===========================
let sym1 = Symbol.for('s1');
console.log(sym1);
let sym2 = Symbol.for('s1');
console.log(sym2);
console.log(sym1 === sym2);
let sym3 = Symbol('s1');
console.log(sym3 === sym1);
let sym4 = Symbol.for();
console.log(sym4);

console.log(Symbol.keyFor(sym1));
console.log(Symbol.keyFor(sym3));
// console.log(Symbol.keyFor("123"));

//=============================3. 使用符号作为属性===========================
console.log("=========================3.使用符号作为属性");
let sym5 = Symbol('foo'),
  sym6 = Symbol("bar"),
  sym7 = Symbol('baz'),
  sym8 = Symbol('qux'),
  sym9 = Symbol('abc'),
  sym10 = Symbol('def');
console.log(sym5);
let obj = {
  name: 'smith',
  age: 19,
  [sym5]: 'this is second'
};
obj[sym6] = 'this is first';
Object.defineProperty(obj, sym7, {
  value: 'this is third'
})
console.log(obj);
console.log(obj[sym7]);
Object.defineProperties(obj, {
  [sym8]: {
    value: 'I AM'
  },
  [sym9]: {
    value: 'IS A'
  },
  [sym10]: {
    value: 'LARGE PIG'
  }
});
console.log(obj);
console.log(obj[sym8]);
console.log(obj[sym9]);
console.log(obj[sym10]);
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getOwnPropertySymbols(obj));
console.log(Object.getOwnPropertyDescriptors(obj));
console.log(Reflect.ownKeys(obj));

let barSymbol = Object.getOwnPropertySymbols(obj).find((item) => {
  return item.toString().match(/bar/)
})
console.log(barSymbol);

const object1 = {
  name: 'zw'
};
Object.defineProperty(object1, 'property1', {
  value: 42,
  writable: false
});

// object1.property1 = 77;
// throws an error in strict mode
console.log(object1);
console.log(object1.name + object1.property1);
console.log(object1.property1);

//=========================Symbol.isConcatSpreadable====================
console.log("=================Symbol.isConcatSpreadable==================");
// let initial = ['foo'];
// let array = ['bar'];
// console.log(array[Symbol.isConcatSpreadable]);
// console.log(initial.concat(array));
// array[Symbol.isConcatSpreadable] = false;
// console.log(initial.concat(array));
let initial = ['foo'];
let array = ['bar'];
console.log(array[Symbol.isConcatSpreadable]); // undefined 
console.log(initial.concat(array)); // ['foo', 'bar'] 
array[Symbol.isConcatSpreadable] = false;
console.log(initial.concat(array));
let initObj = {
  length: 1,
  0: 'baz'
};
console.log(initObj[Symbol.isConcatSpreadable]);
console.log(initial.concat(initObj));
initObj[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(initObj));

let setObj = new Set().add('hello world');
console.log(setObj[Symbol.isConcatSpreadable]);
console.log(initial.concat(setObj));
setObj[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(setObj));



//========================== Symbol.search===============
console.log("==============Symbol.search=====================");
console.log(RegExp.prototype[Symbol.search]);
console.log('fooBar'.search(/Ba/));